package com.bryanbibat.flashcards.robot;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;
import java.util.logging.Logger;

import javax.jdo.JDOHelper;

import com.bryanbibat.flashcards.spring.Deck;
import com.bryanbibat.flashcards.spring.DeckService;
import com.bryanbibat.flashcards.spring.DeckServiceImpl;
import com.bryanbibat.flashcards.spring.Settings;
import com.google.wave.api.AbstractRobotServlet;
import com.google.wave.api.Blip;
import com.google.wave.api.Event;
import com.google.wave.api.EventType;
import com.google.wave.api.Gadget;
import com.google.wave.api.RobotMessageBundle;
import com.google.wave.api.TextView;
import com.google.wave.api.Wavelet;

@SuppressWarnings("serial")
public class FlashcardsRobotServlet extends AbstractRobotServlet {

  public FlashcardsRobotServlet() {
    super();
    DeckServiceImpl service = new DeckServiceImpl();
    service.setPersistenceManagerFactory(JDOHelper.getPersistenceManagerFactory("transactions-optional"));
    deckService = service;
  }
  
  private DeckService deckService;
  
  private static final Logger log = Logger.getLogger(FlashcardsRobotServlet.class.getName());
  
  private static final String WELCOME_MESSAGE = 
    "Flashcard Robot now ready to deal flashcards. \n\n " +
    "To list down the available decks, enter \"list flashcards\" in a new blip. \n " +
    "To get a flashcard deck, enter \"deal [deck ID]\" in a new blip " +
    "followed by any of the following options:  \n\n" +
    "\"[# of rounds] rounds\" - sets the number of round/questions per game. Default is 10. \n" +
    "\"[# of choices] choices\" - sets the number of choices available per round. Default is 3. \n" +
    "\"[penalty weight] penalty\" - sets the number of points deducted per mistake. Default is 1. \n\n" +
    "For example, using the hiragana deck with 20 rounds, 5 choices, and 2 point penalty would be: \n\n" +
    "deal hiragana 20 rounds 5 choices 2 penalty \n\n" +
    "Decks can be submitted at http://wave-flashcards.appspot.com/app/decks";
  
  @Override
  public void processEvents(RobotMessageBundle bundle) {
    Wavelet wavelet = bundle.getWavelet();

    if (bundle.wasSelfAdded()) {
      Blip blip = wavelet.appendBlip();
      TextView textView = blip.getDocument();
      textView.append(WELCOME_MESSAGE);
    }
    
    log.info("Event processed");
    
    for (Event e : bundle.getEvents()) {
      if (e.getType() == EventType.BLIP_SUBMITTED) {
        Blip orig = e.getBlip();
        String origText = orig.getDocument().getText();
        
        if (origText.trim().equalsIgnoreCase("list flashcards")) {
          Blip blip = e.getBlip().createChild();
          TextView textView = blip.getDocument();
          textView.append("Here are the available decks: \n\n");
          List<Deck> decks = deckService.getAll();
          for (Deck deck : decks) {
            textView.append(deck.getId() + " : http://wave-flashcards.appspot.com/app/decks/" + deck.getId() + " \n");
          }
          return;
        } 
        
        CommandParser cp = new CommandParser(origText.trim());
        if (cp.getId() != null) {
          Blip blip = e.getBlip().createChild();
          TextView textView = blip.getDocument();
          Deck deck = deckService.getDeck(cp.getId());
          if (deck == null) {
            textView.append("Flashcard deck \"" + cp.getId() + "\" does not exist.");
            return;
          }
          Settings settings = cp.getSettings();
          
          if (settings.getChoices() > deck.getDeckSize()) {
            settings.setChoices(deck.getDeckSize());
          }
          
          String gadgetUrl = "http://wave-flashcards.appspot.com/app/gadget/";
          try {
            gadgetUrl += URLEncoder.encode(cp.getId(), "UTF-8");
          } catch (UnsupportedEncodingException e1) {
            gadgetUrl += cp.getId();
          }
          gadgetUrl += settings.getURLParams();
          Gadget gameGadget = new Gadget(gadgetUrl);
          
          textView.appendElement(gameGadget);
        } 
        
        
      }
    }
  }

}
